package tools

import (
	"bytes"
	"crypto/ecdsa"
	"crypto/md5"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"encoding/pem"
	"fmt"
	"github.com/ethereum/go-ethereum/common/hexutil"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/golang-jwt/jwt/v4"
	"github.com/mr-tron/base58"
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

type Claims struct {
	Apikey string `json:"apikey"`
	jwt.StandardClaims
}

func MD5(str string) string {
	// 创建一个MD5哈希对象
	hash := md5.New()
	// 写入要加密的数据
	hash.Write([]byte(str))
	// 计算MD5哈希值
	sum := hash.Sum(nil)
	// 将哈希值转换为十六进制字符串
	md5String := hex.EncodeToString(sum)
	return md5String
}

func GenerateToken(apiKey string) (string, error) {
	claims := &Claims{
		Apikey: apiKey,
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString([]byte("my_secret_key"))
	return tokenString, err
}

func ParseToken(tokenString string) (string, error) {
	claims := &Claims{}
	token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
		return []byte("my_secret_key"), nil
	})
	if err != nil || !token.Valid {
		return "", err
	}
	return claims.Apikey, nil
}

func EncryptionKey(chainName string) (string, string, error) {
	var privateKeyHex string
	var address string
	switch chainName {
	case "TRX":
		privateKey, _ := crypto.GenerateKey()
		privateKeyBytes := crypto.FromECDSA(privateKey)
		publicKey := privateKey.Public()
		publicKeyECDSA, _ := publicKey.(*ecdsa.PublicKey)
		addrStr := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
		addrStr = "41" + addrStr[2:]
		addb, _ := hex.DecodeString(addrStr)
		firstHash := sha256.Sum256(addb)
		secondHash := sha256.Sum256(firstHash[:])
		secret := secondHash[:4]
		addb = append(addb, secret...)
		address = base58.Encode(addb)
		privateKeyHex = hexutil.Encode(privateKeyBytes)[2:]
	default:
		// 生成私钥
		privateKey, err := crypto.GenerateKey()
		if err != nil {
			return "", "", err
		}
		// 将私钥转换为字节切片
		privateKeyBytes := crypto.FromECDSA(privateKey)
		// 将字节切片转换为十六进制字符串
		privateKeyHex = hex.EncodeToString(privateKeyBytes)
		// 生成公钥
		publicKey := privateKey.Public().(*ecdsa.PublicKey)
		// 生成地址
		address = crypto.PubkeyToAddress(*publicKey).Hex()
	}

	encryPrivateKey, err := encryptWithPublicKeyFromFile(privateKeyHex)
	if err != nil {
		return "", "", err
	}

	return address, encryPrivateKey, nil
}

func encryptWithPublicKeyFromFile(message string) (string, error) {
	// 从文件读取公钥
	publicKeyData, err := os.ReadFile("public_key.pem")
	if err != nil {
		return "", err
	}

	// 解析PEM格式的公钥
	block, _ := pem.Decode(publicKeyData)
	if block == nil || block.Type != "PUBLIC KEY" {
		return "", fmt.Errorf("公钥文件格式错误")
	}

	// 解析PKIX格式的公钥
	pub, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return "", err
	}

	publicKey, ok := pub.(*rsa.PublicKey)
	if !ok {
		return "", fmt.Errorf("公钥解析失败")
	}

	// 加密消息
	messageBytes := []byte(message)
	encryptedBytes, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, messageBytes, nil)
	if err != nil {
		return "", err
	}

	return base64.StdEncoding.EncodeToString(encryptedBytes), nil
}

func SendGet(url string) ([]byte, error) {
	// 将data转换为json字节数组
	jsonData, err := json.Marshal(nil)
	if err != nil {
		log.Println("jsonData error:", err)
		return nil, err
	}

	// 创建http请求
	req, err := http.NewRequest("GET", url, bytes.NewBuffer(jsonData))
	if err != nil {
		log.Println("NewRequest error:", err)
		return nil, err
	}

	// 发送请求
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Println("Do error:", err)
		return nil, err
	}
	defer resp.Body.Close()

	// 读取响应内容
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println("body error:", err)
		return nil, err
	}

	return body, nil
}
